package com.shycloud.mido.organ.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shycloud.mido.common.core.constant.CommonConstants;
import com.shycloud.mido.common.core.util.R;
import com.shycloud.mido.common.security.service.ShyMember;
import com.shycloud.mido.common.security.util.SecurityUtils;
import com.shycloud.mido.member.api.entity.AtvMediaSpace;
import com.shycloud.mido.organ.api.dto.DiaryDTO;
import com.shycloud.mido.organ.api.dto.DiaryReviewDto;
import com.shycloud.mido.organ.api.entity.DiaryComment;
import com.shycloud.mido.organ.api.entity.DiaryEntity;
import com.shycloud.mido.organ.api.entity.MemberEntity;
import com.shycloud.mido.organ.api.entity.MiniInteraction;
import com.shycloud.mido.organ.api.entity.MiniMessage;
import com.shycloud.mido.organ.api.entity.WorksEntity;
import com.shycloud.mido.organ.mapper.AtvMediaSpaceMapper;
import com.shycloud.mido.organ.mapper.DiaryCommentMapper;
import com.shycloud.mido.organ.mapper.DiaryMapper;
import com.shycloud.mido.organ.mapper.InteractionMapper;
import com.shycloud.mido.organ.mapper.MemberMapper;
import com.shycloud.mido.organ.mapper.MessageMapper;
import com.shycloud.mido.organ.mapper.MiniFollowedMapper;
import com.shycloud.mido.organ.mapper.WorksMapper;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;

@RestController
@AllArgsConstructor
@RequestMapping("/diary")
public class DiaryController {

	private WorksMapper worksMapper;
	private DiaryMapper diaryMapper;
	private DiaryCommentMapper diaryCommentMapper;
	private MiniFollowedMapper followedMapper;
	private MessageMapper messageMapper;
	private InteractionMapper interactionMapper;
	private MemberMapper memberMapper;
	private AtvMediaSpaceMapper atvMediaSpaceMapper;

	//获取他人日记接口
	@GetMapping("/getDiaryByMemberId")
	public R getDiaryByMemberId(Page<DiaryDTO> page, String myMemberId, String otherMemberId) {
		//需要判定关注关系
		IPage<DiaryDTO> result = new Page();
		if (isFriend(myMemberId, otherMemberId)) {
			result = diaryMapper.getFriendDiary(page, otherMemberId);
		} else {
			result = diaryMapper.getNoFriendDiary(page, otherMemberId);
		}
		addFirstComment(result);
		return new R<>(result);
	}

	@GetMapping("/getMyDiary")
	public R getMyDiary(Page<DiaryDTO> page, String memberId, String status) {

		String[] statusArr = status.split(",");

		IPage<DiaryDTO> result = diaryMapper.getMyDiary(page, memberId, statusArr);
		addFirstComment(result);
		return new R<>(result);
	}

	@Transactional
	@PostMapping("/addDiary")
	public R addDiary(@RequestBody DiaryEntity diary) {

		String memberId = diary.getMemberId();
		MemberEntity memberEntity = memberMapper.selectById(memberId);

		if ("1".equals(memberEntity.getMiniStatus())) {
			return new R(CommonConstants.FAIL, "您的账号已被禁用，请联系客服电话 4000123485 进行处理。", false);
		}

		int result = 0;
		//若为视频日记且是自动同步到作品时则创建作品
		if (diary.getType() == 1 && diary.getIsWorks() == 1) {
			WorksEntity works = new WorksEntity();
			works.setMemberId(diary.getMemberId());
			works.setSrc(diary.getSrc());
			works.setPermission(diary.getPermission());
			works.setText(diary.getText());
			result += worksMapper.insert(works);
			diary.setWorksId(works.getId());
		}
		result += diaryMapper.insert(diary);
		return new R<>(result);
	}

	@Transactional
	@PostMapping("/addDiaryAtv")
	public R<Integer> addDiaryAtv(@RequestBody DiaryEntity diary) {
		int result = 0;
		//若为视频日记且是自动同步到作品时则创建作品
		if (diary.getType() == 1 && diary.getIsWorks() == 1) {
			WorksEntity works = new WorksEntity();
			works.setMemberId(diary.getMemberId());
			works.setSrc(diary.getSrc());
			works.setPermission(diary.getPermission());
			works.setText(diary.getText());
			result += worksMapper.insert(works);
			diary.setWorksId(works.getId());
		}
		result += diaryMapper.insert(diary);
		if (0 == result) {
			return new R<>(CommonConstants.FAIL, "保存失败", null);
		}
		return new R<>(diary.getId());
	}

	//删除日记同事删除作品
	@Transactional
	@GetMapping("/deleteById")
	public R deleteById(int id) {

		interactionMapper.delete(new QueryWrapper<MiniInteraction>().eq("target_id", id));

		//先删除与日记相关的评论
		diaryCommentMapper.delete(new QueryWrapper<DiaryComment>().eq("diary_id", id));

		//如果关联作品，将作品也删除
		DiaryEntity diaryEntity = diaryMapper.selectById(id);

		if (diaryEntity.getIsWorks() == 1) {
			worksMapper.deleteById(diaryEntity.getWorksId());
		}

		return new R(diaryMapper.deleteById(id));
	}

	@Transactional
	@PostMapping("/addComment")
	public R addComment(@RequestBody DiaryComment comment) {
		int result = 0;
		if (!comment.getFatherId().equals("-1")) {
			//当回复某条评论时, 更新父评论状态
			DiaryComment father = diaryCommentMapper.selectById(comment.getFatherId());
			father.setHasChild(1);
			diaryCommentMapper.updateById(father);
		}
		result += diaryCommentMapper.insert(comment);
		//增加互动信息
		MemberEntity member = memberMapper.selectById(comment.getMemberId());
		DiaryEntity diary = diaryMapper.selectById(comment.getDiaryId());
		MiniInteraction interaction = new MiniInteraction();
		interaction.setFromMemberId(comment.getMemberId());
		interaction.setFromMemberName(member.getShowname());
		interaction.setCommentId(comment.getId());
		interaction.setType(0);
		interaction.setToMemberId(diary.getMemberId());
		interaction.setTargetId(comment.getDiaryId());
		interaction.setText(member.getShowname() + "评论了您的日记");
		result += interactionMapper.insert(interaction);
		return new R<>(result);
	}

	@GetMapping("/getComment")
	public R getComment(Page<DiaryComment> page, String diaryId) {
		return new R<>(diaryCommentMapper.getComment(page, diaryId));
	}

	@GetMapping("/getCommentDetail")
	public R getCommentDetail(Page<DiaryComment> page, String diaryId, String fatherId) {
		return new R<>(diaryCommentMapper.getCommentDetail(page, diaryId, fatherId));
	}

	//下面是后台接口
	@GetMapping("/getReviewPage")
	public R getReviewPage(Page<DiaryReviewDto> page, String phone, String startDate, String endDate, String status,String recommendFlag) {
		/** '推荐标记 : 0不推荐1推荐'*/
		if (StringUtils.isBlank(recommendFlag)) {
			recommendFlag = "0";
		}
		return new R<>(diaryMapper.getReviewPage(page, phone, startDate, endDate, status,recommendFlag));
	}
	
	//设置推荐
	@PostMapping("/setRecommend")
	@ApiOperation("后台--设为推荐：审核通过，同步作品，公开的才能设置为推荐")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "主键", paramType = "query", dataType = "string", required = true),
			@ApiImplicitParam(name = "recommendFlag", value = "推荐标记 : 0不推荐1推荐", paramType = "query", dataType = "string", required = true)
	})
	public R<Boolean> setRecommend(@RequestBody DiaryEntity diary) {
			/** '推荐标记 : 0不推荐1推荐'*/
			if (StringUtils.isBlank(diary.getRecommendFlag())) {
				return new R<>(CommonConstants.FAIL, "推荐标记必填", false);
			}
			if (Objects.isNull(diary.getId())) {
				return new R<>(CommonConstants.FAIL, "id必填", false);
			}
			if (StringUtils.equals("1", diary.getRecommendFlag())) {
				//设置推荐 不能超过20个 随机获取N个
				LambdaQueryWrapper<DiaryEntity> queryWrapper = Wrappers.<DiaryEntity>lambdaQuery()
						.eq(DiaryEntity::getRecommendFlag, diary.getRecommendFlag());
				
				Integer selectCount = diaryMapper.selectCount(queryWrapper);
				if (Objects.isNull(selectCount) || selectCount >= 20) {
					return new R<>(CommonConstants.FAIL, "推荐不能超过20个", false);
				}
			}
			//CHECK
			DiaryEntity check = diaryMapper.selectById(diary.getId());
			if (0 == check.getPermission() && 1 == check.getIsWorks() && 1 ==  check.getStatus()  && 1 ==  check.getType()) {
				//更新
				LambdaUpdateWrapper<DiaryEntity> updateWrapper = Wrappers.<DiaryEntity>lambdaUpdate()
						.set(DiaryEntity::getRecommendFlag, diary.getRecommendFlag())
						.eq(DiaryEntity::getId, diary.getId());
				diaryMapper.update(null, updateWrapper);
				return new R<Boolean>(true);
			}
			return new R<>(CommonConstants.FAIL, "审核通过，同步广场，公开的，视频才能设置为推荐", false);
			
	}
	//设置推荐
	@GetMapping("/getRecommendForMiniHome")
	@ApiOperation("小程序首页-广场推荐")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "size", value = "大小", paramType = "size", dataType = "int", required = true)
	})
	public R<List<DiaryReviewDto>> getRecommendForMiniHome(Integer size) {
		if (Objects.isNull(size)) {
			return new R<>(CommonConstants.FAIL, "随机数量必填", null);
		}
		ShyMember member = SecurityUtils.getMember();
		List<DiaryReviewDto> records = null;
		if (Objects.isNull(member)) {
			records = diaryMapper.getRecommendForMiniHome(size);
		}else {
			records = diaryMapper.getRecommendForMiniHomeByMemberId(member.getId(),size);
		}
		if (CollectionUtils.isEmpty(records)) {
			return new R<>(CommonConstants.FAIL, "没有广场推荐", null);
		}
		
		if (records.size() <= size) {
			return new R<List<DiaryReviewDto>>(records);
		}
        List<DiaryReviewDto> listRandom = new ArrayList<>();
        
        //随机取出size条推荐
        for (int i = 0; i < size; i++) {
        	 Random random = new Random();
        	 int removeIndex = random.nextInt(records.size()-1);
        	 listRandom.add(records.get(removeIndex));
        	 records.remove(removeIndex);
		}
		return new R<List<DiaryReviewDto>>(listRandom);
	}
//	public static void main(String[] args) {
//		List<Integer> records = new ArrayList<>();
//		records.add(1);
//		records.add(2);
//		records.add(3);
//		records.add(4);
//		records.add(5);
//		records.add(6);
//		records.add(7);
//		records.add(8);
//		List<Integer> list = new ArrayList<>();
//		//随机取出size条推荐
//        for (int i = 0; i < 3; i++) {
//        	 Random random = new Random();
//        	 int removeIndex = random.nextInt(records.size()-1);
//        	 list.add(records.get(removeIndex));
//        	 records.remove(removeIndex);
//		}
//        System.out.println(JSON.toJSON(list));
//	}
	//如修改日记审核状态, 同步修改作品状态
	//status: 审核状态(0:未审核, 1:通过, 2:拒绝)
	@PostMapping("/updateById")
	public R updateById(@RequestBody DiaryEntity diary) {
		int result = 0;
		//拒绝则插入消息
		DiaryEntity d = diaryMapper.selectById(diary.getId());
		if (diary.getStatus() == 2) {
			MiniMessage message = new MiniMessage();
			message.setMemberId(d.getMemberId());
			message.setText("亲爱的用户, 您上传的日记 ( 编号:" + diary.getId() + " ) 因内容不符合规定, 未能通过审核");
			result += messageMapper.insert(message);
		}

		if (d.getIsWorks() == 1) {
			//获取作品ID
			WorksEntity worksEntity = worksMapper.selectById(d.getWorksId());
			worksEntity.setStatus(diary.getStatus());
			result += worksMapper.updateById(worksEntity);
		}
		if (StringUtils.equals("1", d.getIsAtvSpace())) {
			//上传到活动相册
			AtvMediaSpace atvMediaSpace = atvMediaSpaceMapper.selectById(d.getAtvSpaceId());
			atvMediaSpace.setStatus(String.valueOf(diary.getStatus()));
			atvMediaSpaceMapper.updateById(atvMediaSpace);
		}

		result += diaryMapper.updateById(diary);
		return new R<>(result);
	}

	//判断是否为好友
	private Boolean isFriend(String myMemberId, String otherMemberId) {
		//互相关注即为好友
		QueryWrapper from = new QueryWrapper<>();
		from.eq("member_id", otherMemberId);
		from.eq("to_member_id", myMemberId);
		Integer fromNum = followedMapper.selectCount(from);

		QueryWrapper to = new QueryWrapper<>();
		to.eq("member_id", myMemberId);
		to.eq("to_member_id", otherMemberId);
		Integer toNum = followedMapper.selectCount(to);

		if (fromNum != 0 && toNum != 0) {
			return true;
		} else {
			return false;
		}
	}

	//塞入日记一级评论
	private void addFirstComment(IPage<DiaryDTO> page) {
		for (DiaryDTO dto : page.getRecords()) {
			QueryWrapper queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("diary_id", dto.getId());
			queryWrapper.eq("father_id", -1);
			dto.setCommentList(diaryCommentMapper.selectList(queryWrapper));
		}
	}

}
